package controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

import model.Frame;
import model.MP3File;
/**
 * a class with static methods to write the data from a MP3File object into a mp3 file
 *
 *
 */
public class ID3Writer {

	/**
	 * writes new mp3 with the tag from a MP3File object and the musicdata from a mp3 file
	 * @param mp3
	 * @throws Exception
	 */
	public static void writeMP3ToFile(MP3File mp3) throws Exception{
		/*
		 * get music data
		*/
		File file = mp3.getMp3File();
		byte fileContent[] = new byte[(int)file.length()];
		try(FileInputStream inputStream = new FileInputStream(file)) {         
	        inputStream.read(fileContent);
	        inputStream.close();
		} catch(IOException e) {
			e.getStackTrace();
		}
		byte musicData[] = new byte[(int)file.length()- mp3.getOriginalTagSize()];
		System.arraycopy(fileContent, mp3.getOriginalTagSize(), musicData, 0, musicData.length);
		
		String path = file.getPath();
		
		if(!file.delete()) {
			throw new IOException("Could not delete old file!");
		}
		System.out.println("deleted old file");
		
		File newFile = Files.createFile(Paths.get(path)).toFile();
		
		try(FileOutputStream fileOutputStream = new FileOutputStream(file)) {
			fileOutputStream.write(mp3.getId3Tag().getHeader());
			//create tag
			byte newTag[] = new byte[mp3.getId3Tag().getSize()+10];
			int offset = 0;
			System.arraycopy(mp3.getId3Tag().getHeader(), 0, newTag, offset, 10);
			/*
			 * write frames
			 */
			for(Frame f : mp3.getId3Tag().getListOfUsedFrames()){
				System.arraycopy(f.getData(), 0, newTag, offset, f.getSize());
				offset += f.getSize();
			}
			for(Frame f : mp3.getId3Tag().getListOfOtherFrames()){
				System.arraycopy(f.getData(), 0, newTag, offset, f.getSize());
				offset += f.getSize();
			}			
			fileOutputStream.write(newTag);
			fileOutputStream.write(musicData);
		} catch(IOException e) {
			e.getStackTrace();
		}
		mp3.setMp3File(newFile);
		System.out.println("Erfolgreich gespeichert");
		
	}

	/**
	 * create new Textframe
	 * @param mp3
	 * @param key
	 * @param value
	 */
	public static void changeContentMP3FrameWithKey(MP3File mp3, String key, String value){
		
		Frame frame = mp3.getId3Tag().getFrame(key);
		if(frame == null) return;
		byte[] title = key.getBytes();	//create titlebytes
		
		boolean unicode = frame.getData()[10] == 1;
		byte[] content;
		if(unicode) {
			content = value.getBytes(Charset.forName("UTF-16"));
		} else {
			content = value.getBytes(Charset.forName("ISO-8859-1"));
		}	//created contentbytes
		
		int newFrameSize = 11 + content.length;
		byte[] newSize = ID3Parser.intToByteArrayFrame(newFrameSize-10); // created sizebytes
		byte[] flag = new byte[2];
		System.arraycopy(frame.getData(), 8, flag, 0, 2); //created flagbytes
		
		byte[] newFrame = new byte[newFrameSize];
		System.arraycopy(title, 0, newFrame, 0, 4);
		System.arraycopy(newSize, 0, newFrame, 4, 4);
		System.arraycopy(flag, 0, newFrame, 8, 2);
		newFrame[10] = frame.getData()[10];
		System.arraycopy(content, 0, newFrame, 11, content.length); //new frame merged
			
		mp3.getId3Tag().addUsedFrame(key, new Frame((newFrameSize), newFrame));
		mp3.getId3Tag().resize(); //calculate new Size
		
		byte[] newTagSizeBytes = ID3Parser.intToByteArrayTag(mp3.getId3Tag().getSize()); //calculate new header size bytes
		System.arraycopy(newTagSizeBytes, 0, mp3.getId3Tag().getHeader(), 6, 4);	//change size bytes in header
		
	}
	
	/**
	 * create new APIC frame
	 * @param mp3
	 * @param key
	 * @param value
	 */
	public static void changeContentMP3FrameWithKey(MP3File mp3, String key, byte[] imageData){
		
		Frame frame = mp3.getId3Tag().getFrame(key);
		if(frame == null) return;
		byte[] title = key.getBytes();	//create titlebytes
		byte[] flag = new byte[2];
		System.arraycopy(frame.getData(), 8, flag, 0, 2); //created flagbytes
		byte[] picHeader = new byte[] { 0,											//encoding
									"P".getBytes(Charset.forName("ISO-8859-1"))[0],
									"N".getBytes(Charset.forName("ISO-8859-1"))[0],
									"G".getBytes(Charset.forName("ISO-8859-1"))[0], //MIME type
									 0,											//MIME terminal
									 3,											//Picture type
									 0 };										//Picture Description
										
		int newFrameSize = 10 + picHeader.length + imageData.length;
		byte[] newSize = ID3Parser.intToByteArrayFrame(newFrameSize-10); // created sizebytes
		byte[] newFrame = new byte[newFrameSize];
		
		System.arraycopy(title, 0, newFrame, 0, 4);
		System.arraycopy(newSize, 0, newFrame, 4, 4);
		System.arraycopy(flag, 0, newFrame, 8, 2);
		System.arraycopy(picHeader, 0, newFrame, 10, picHeader.length);
		System.arraycopy(imageData, 0, newFrame, 10+picHeader.length, imageData.length); //new frame merged

		mp3.getId3Tag().addUsedFrame(key, new Frame((newFrameSize), newFrame));
		mp3.getId3Tag().resize(); //calculate new Size
		
		byte[] newTagSizeBytes = ID3Parser.intToByteArrayTag(mp3.getId3Tag().getSize()); //calculate new header size bytes
		System.arraycopy(newTagSizeBytes, 0, mp3.getId3Tag().getHeader(), 6, 4);	//change size bytes in header
		System.out.println("content changend");
	}
}
